﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;

namespace QRHelper
{
    public class QR
    {
        public delegate void GetQrcode(string qrcode);
        public static event GetQrcode OnGetQrcode;
        public delegate void StartReader();
        public static event StartReader OnStartReader;
        static System.Timers.Timer readqr = null;
        public static bool IsReaded = false;
        
        [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
        public struct PortParam
        {
            public Int16 portNo;
            public UInt32 baudRate;
        };

        /*
         * 定义DLL接口托管函数
         */

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate void CALL_BACK_DATA(IntPtr dataPtr, uint length, uint userdata);

        [DllImport("ZBCR.dll", EntryPoint = "ZBCR_Open", CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
        static extern int ZBCR_Open(IntPtr pParam, CALL_BACK_DATA pfnReadData, uint userdata);


        [DllImport("ZBCR.dll", EntryPoint = "ZBCR_Close", CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
        static extern int ZBCR_Close();


        [DllImport("ZBCR.dll", EntryPoint = "ZBCR_StartScan", CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
        static extern int ZBCR_StartScan();
        [DllImport("ZBCR.dll", EntryPoint = "ZBCR_StopScan", CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
        static extern int ZBCR_StopScan();

        [DllImport("ZBCR.dll", EntryPoint = "ZBCR_ControlCmd", CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
        static extern int ZBCR_ControlCmd(byte[] pInputBuffer, uint nBytesInInputBuffer,
                                        byte[] pOutputBuffer, uint nSizeOfOutputBuffer, ref uint pnBytesReturned);


        [DllImport("ZBCR.dll", EntryPoint = "ZBCR_SetupRead", CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
        static extern int ZBCR_SetupRead(byte[] pInputBuffer, uint nBytesInInputBuffer,
                                        byte[] pOutputBuffer, uint nSizeOfOutputBuffer, ref uint pnBytesReturned);

        [DllImport("ZBCR.dll", EntryPoint = "ZBCR_SetupWrite", CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
        static extern int ZBCR_SetupWrite(byte[] pInputBuffer, uint nBytesInInputBuffer,
                                        byte[] pOutputBuffer, uint nSizeOfOutputBuffer, ref uint pnBytesReturned);

        //初始化回调函数
        static CALL_BACK_DATA fd = new CALL_BACK_DATA(ReadData);

        //解码成功后的数据输出回调函数
        public static void ReadData(IntPtr dataPtr, uint length, uint userdata)
        {
            try
            {
                readqr.Enabled = false;
                int len = (int)length;
                byte[] data = new byte[len];
                Marshal.Copy(dataPtr, data, 0, len);
                string hex = BitConverter.ToString(data, 0, len);
                string charstr = System.Text.Encoding.ASCII.GetString(data);
                
                OnGetQrcode(charstr);
            }
            catch
            {

            }
        }

        static byte[] buffer = new byte[1024];
        static byte[] bsp_cmd = new byte[10];
        static uint size = (uint)buffer.Length;
        static uint bytesReturned = 0;

        public static bool ConnectQrcode(short port, uint baundate)
        {
            bool result = false;
            try
            {
                //COM端口初始化
                PortParam pp = new PortParam();
                pp.portNo = port;
                pp.baudRate = baundate;
                IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(pp));
                // Copy the struct to unmanaged memory.
                Marshal.StructureToPtr(pp, pnt, true);

                //连接端口，并传入解码输出回调函数
                int res = ZBCR_Open(pnt, fd, 0);
                if (res == 1) result = true;
            }
            catch (Exception err)
            { }
            return result;
        }
        public static void StartRead()
        {
            if (!readqr.Enabled)
            {
                ZBCR_StartScan();
                readqr.Enabled = true;
            }
        }
        public static void StopRead()
        {
            if (readqr.Enabled)
            {
                readqr.Enabled = false;
                ZBCR_StopScan();

            }
            ZBCR_StopScan();
            ZBCR_Close();
        }
        public static void InitQR(int intervalTimes)
        {
            readqr = new System.Timers.Timer();
            readqr.Interval = intervalTimes;
            readqr.Elapsed += new System.Timers.ElapsedEventHandler(readqr_Elapsed);
        }

        static void readqr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            StopRead();
            OnStartReader();
        }

        public static int StartPerssMode()
        {
            bsp_cmd[0] = 0x21;//PID_QR_CODE
            bsp_cmd[1] = 0x61;//FID_QR_ACTIVE
            bsp_cmd[2] = 0x41;//触发模式
            bsp_cmd[3] = 0x00;//按键模式
           return ZBCR_SetupWrite(bsp_cmd, 4, buffer, size, ref bytesReturned);

        }

        public static int StartInductionMode()
        {
            //bsp_cmd[0] = 0x21;//PID_QR_CODE
            bsp_cmd[0] = 0x61;//FID_QR_ACTIVE
            bsp_cmd[1] = 0x41;//触发模式
            bsp_cmd[2] = 0x02;//感应模式
            int res= ZBCR_SetupWrite(bsp_cmd, 3, buffer, size, ref bytesReturned);
            return res;
        }

    }
}
